import { defineComponent, Component, markRaw, onMounted, ref, getCurrentInstance } from 'vue';
import { NCollapse, NTabPane, NTabs } from 'naive-ui';
import { Element, Connection, Label, Shape } from 'diagram-js/lib/model/Types';
import { Translate } from 'diagram-js/lib/i18n/translate';
import { debounce } from 'lodash-es';
import { is } from 'bpmn-js/lib/util/ModelUtil';

import EventEmitter from '@wf/components/bpmnjs/utils/EventEmitter';
import modelerStore from '@wf/components/bpmnjs/store/modeler';
import Logger from '@wf/components/bpmnjs/utils/Logger';

import getBpmnIconType from '@wf/components/bpmnjs/bpmn-icons/getIconType';
import bpmnIcons from '@wf/components/bpmnjs/bpmn-icons';
import BpmnIcon from '@wf/components/bpmnjs/components/common/BpmnIcon.vue';

// import { isAsynchronous } from '@wf/components/bpmnjs/bo-utils/asynchronousContinuationsUtil';
// import { isExecutable } from '@wf/components/bpmnjs/bo-utils/executionListenersUtil';
// import { isJobExecutable } from '@wf/components/bpmnjs/bo-utils/jobExecutionUtil';
// import { isStartInitializable, isUserAssignmentSupported } from '@wf/components/bpmnjs/bo-utils/initiatorUtil';
import { isAssignee } from '@wf/components/bpmnjs/bo-utils/assigneeUtil';
import { isGateway } from '@wf/components/bpmnjs/bo-utils/gatewayUtil';

// import ElementGenerations from './components/ElementGenerations.vue';
// import ElementConditional from './components/ElementConditional.vue';
// import ElementDocumentations from './components/ElementDocumentations.vue';
// import ElementExecutionListeners from './components/ElementExecutionListeners.vue';
// import ElementExtensionProperties from './components/ElementExtensionProperties.vue';
// import ElementAsyncContinuations from './components/ElementAsyncContinuations.vue';
// import ElementJobExecution from './components/ElementJobExecution.vue';
// import ElementStartInitiator from './components/ElementStartInitiator.vue';
import ElementAssignee from './code-components/ElementAssignee.vue';
import ElementBasicInfo from './code-components/ElementBasicInfo.vue';
import ElementCondition from './code-components/ElementCondition.vue';
import ElementEvents from './code-components/ElementEvents.vue';
import ElementVariables from './code-components/ElementVariables.vue';
import ElementGateway from './code-components/ElementGateway.vue';
import ElementSubProcess from './code-components/ElementSubProcess.vue';
import ElementCallActivity from './code-components/ElementCallActivity.vue';
import ElementServiceTask from './code-components/ElementServiceTask.vue';
import ElementVariableSetTask from './code-components/ElementVariableSetTask.vue';
import ElementVariablePrintTask from './code-components/ElementVariablePrintTask.vue'

// import UserAssignment from './components/UserAssignment.vue';

import { isCanbeConditional } from '@wf/components/bpmnjs/bo-utils/conditionUtil';
import { customTranslate } from '@wf/components/bpmnjs/additional-modules/Translate';
import { getTabLabel } from './code-components/PanelSetting';
import { useI18n } from 'vue-i18n';
import { ElForm, ElIcon, ElTabPane, ElTabs } from 'element-plus';
import { DArrowLeft, DArrowRight } from '@element-plus/icons';

const Panel = defineComponent({
  name: 'PropertiesPanel',
  setup() {
    const { t } = useI18n();
    const modeler = modelerStore();
    const panel = ref<HTMLDivElement | null>(null);
    const currentElementId = ref<string | undefined>(undefined);
    const currentElementType = ref<string | undefined>(undefined);
    const currentServiceTaskType = ref<string | undefined>(undefined);

    const penalTitle = ref<string | undefined>('属性配置');
    const bpmnIconName = ref<string>('Process');
    const bpmnElementName = ref<string>('Process');
    const tabActive = ref<string>(''); // 设置默认打开的tab页

    const renderComponents = ref<Component[]>([]);
    const isCollapse = ref<Boolean>(false); // 是否折叠

    const setCurrentComponents = (element: BpmnElement) => {
      console.log('执行了setCurrentComponents', element);
      // 清空
      renderComponents.value.splice(0, renderComponents.value.length);
      // renderComponents.push(ElementGenerations)
      // renderComponents.push(ElementDocumentations)
      renderComponents.value.push(ElementBasicInfo);
      is(element, 'bpmn:Process') && renderComponents.value.push(ElementEvents, ElementVariables);
      isAssignee(element) && renderComponents.value.push(ElementAssignee);
      isCanbeConditional(element) && renderComponents.value.push(ElementCondition);
      isGateway(element) && renderComponents.value.push(ElementGateway);
      (is(element, 'bpmn:SubProcess') || is(element, 'bpmn:Transaction')) && renderComponents.value.push(ElementSubProcess);
      is(element, 'bpmn:CallActivity') && renderComponents.value.push(ElementCallActivity);
      is(element, 'bpmn:ServiceTask') && element.businessObject.taskType == 'ApiServiceTask' && renderComponents.value.push(ElementServiceTask);
      is(element, 'bpmn:ServiceTask') && element.businessObject.taskType == 'SetVariableServiceTask' && renderComponents.value.push(ElementVariableSetTask);
      is(element, 'bpmn:ServiceTask') && element.businessObject.taskType == 'OutputVariableServiceTask' && renderComponents.value.push(ElementVariablePrintTask);
      // isJobExecutable(element) && renderComponents.push(ElementJobExecution)
      // renderComponents.push(ElementExtensionProperties)
      // isExecutable(element) && renderComponents.push(ElementExecutionListeners)
      // isAsynchronous(element) && renderComponents.push(ElementAsyncContinuations)
      // isStartInitializable(element) && renderComponents.push(ElementStartInitiator)
      // isUserAssignmentSupported(element) && renderComponents.push(UserAssignment)
    };

    // 设置选中元素，更新 store
    const setCurrentElement = debounce((element: Shape | Element | Connection | Label | null, event: string) => {
      let activatedElement: BpmnElement | undefined = element;
      let activatedElementTypeName = '';

      if (!activatedElement) {
        activatedElement = modeler.getElRegistry?.find((el) => el.type === 'bpmn:Process') || modeler.getElRegistry?.find((el) => el.type === 'bpmn:Collaboration');

        if (!activatedElement) {
          return Logger.prettyError('No Element found!');
        }
      }
      activatedElementTypeName = getBpmnIconType(activatedElement);

      modeler.setElement(markRaw(activatedElement));
      currentElementId.value = activatedElement.id;
      currentElementType.value = activatedElement.type.split(':')[1];
      if(currentElementType.value == 'ServiceTask'){
        currentServiceTaskType.value = activatedElement.businessObject.taskType;
      }else{
        currentServiceTaskType.value = undefined;
      }

      penalTitle.value = modeler.getModeler?.get<Translate>('translate')(currentElementType.value);
      bpmnIconName.value = bpmnIcons[activatedElementTypeName];
      bpmnElementName.value = activatedElementTypeName;

      setCurrentComponents(activatedElement);
      console.log('触发事件为', event);
      // 当点击改变选中节点时，重置默认tab页
      if (event == 'selection.changed' || event == 'import.done') {
        tabActive.value = renderComponents.value[0].name as string;
      }
      EventEmitter.emit('element-update', activatedElement);

      Logger.prettyPrimary('Selected element changed', `ID: ${activatedElement.id} , type: ${activatedElement.type}`);
    }, 100);

    EventEmitter.on('modeler-init', (modeler) => {
      // 导入完成后默认选中 process 节点
      modeler.on('import.done', () => {
        setCurrentElement(null, 'import.done');
      });
      // 监听选择事件，修改当前激活的元素以及表单
      modeler.on('selection.changed', ({ newSelection }) => {
        setCurrentElement(newSelection[0] || null, 'selection.changed');
      });
      modeler.on('element.changed', ({ element }) => {
        // 保证 修改 "默认流转路径" 等类似需要修改多个元素的事件发生的时候，更新表单的元素与原选中元素不一致。
        if (element && element.id === currentElementId.value) {
          setCurrentElement(element, 'element.changed');
        }
      });

      modeler.on('element.click', (event) => {
        Logger.prettyInfo('Element Click', event);
      });
    });

    // 面板折叠按钮
    const handelToggleBtnClick = () => {
      isCollapse.value = !isCollapse.value;
    };

    onMounted(() => !currentElementId.value && setCurrentElement(null, 'mounted'));

    return () => (
      <div ref={panel} class={{ panel: true, close: isCollapse.value }}>
        <div class="toggle-btn" onClick={handelToggleBtnClick}>
          <ElIcon>{!isCollapse.value ? <DArrowRight /> : <DArrowLeft />}</ElIcon>
        </div>
        <div class="panel-header">
          <BpmnIcon name={bpmnIconName.value}></BpmnIcon>
          <p>{bpmnElementName.value}</p>
          <p>{customTranslate(currentServiceTaskType.value ? currentServiceTaskType.value : currentElementType.value || 'Process')}</p>
        </div>
        {renderComponents.value && !!renderComponents.value.length && (
          <ElTabs type="border-card" v-model={tabActive}>
            {renderComponents.value.map(
              (component) =>
                !!component.name && (
                  <ElTabPane name={component.name as string} label={String(t(getTabLabel(component.name as string)))}>
                    <ElForm labelWidth={100}>
                      <component is={component}></component>
                    </ElForm>
                  </ElTabPane>
                )
            )}
          </ElTabs>
          // <NTabs size="large" animated defaultValue={renderComponents[0].name}>
          //   {renderComponents.map(
          //     (component) =>
          //       !!component.name && (
          //         <NTabPane
          //           name={component.name as string}
          //           tab={String(t(getTabLabel(component.name as string)))}
          //         >
          //           <component is={component}></component>
          //         </NTabPane>
          //       )
          //   )}
          // </NTabs>
        )}
        {/* <NCollapse arrow-placement="right">
          {renderComponents.map((component) => (
            <component is={component}></component>
          ))}
        </NCollapse> */}
      </div>
    );
  }
});

export default Panel;
